
#ifndef FH_STEPMOTOR_HW_H_
#define FH_STEPMOTOR_HW_H_

#include <linux/ioctl.h>





#define MAX_FHSM_NR (2)



#define MOTOR_CTRL     (0x0)
#define MOTOR_RESET    (0x4)
#define MOTOR_MODE     (0x8)
#define MOTOR_TIMING0     (0xc)
#define MOTOR_TIMING1     (0x10)
#ifdef CONFIG_FH_STEPMOTOR_V1_1
#define MOTOR_INIT     (0x14)
#define MOTOR_DEBOUNCE     (0x18)
#define MOTOR_MANUAL_CONFIG0     (0x1c)
#define MOTOR_MANUAL_CONFIG1     (0x20)
#define MOTOR_INT_EN     (0x24)
#define MOTOR_INT_STATUS     (0x28)
#define MOTOR_STATUS0     (0x2c)
#else
#define MOTOR_MANUAL_CONFIG0     (0x14)
#define MOTOR_MANUAL_CONFIG1     (0x18)
#define MOTOR_INT_EN     (0x1c)
#define MOTOR_INT_STATUS     (0x20)
#define MOTOR_STATUS0     (0x24)
#endif
#ifdef CONFIG_FH_STEPMOTOR_V1_2
#define MOTOR_KEEP	(0x48)
#endif

#define MOTOR_MEM     (0x100)



enum fh_sm_mode {
	fh_sm_constant = 0,
	fh_sm_high = 1,
	fh_sm_manual_4 = 2,
	fh_sm_manual_8 = 3,
};
struct fh_sm_timingparam {
	int period;
	int counter;
	int copy;
	int microstep;
};
#ifdef CONFIG_FH_STEPMOTOR_V1_1
struct fh_sm_param_init {
	int NeedInit;
	int InitRunNum;
	int NeedUpdatePos;
	int InitStep;
	int InitMicroStep;
};

struct fh_sm_param_autostop {
	int AutoStopEn;
	int AutoStopSigPol;
	int AutoStopSigDeb;
	int AutoStopSigDebSet;
	int AutoStopChechGPIO;
};
#endif
#ifdef CONFIG_FH_STEPMOTOR_V1_2
struct fh_sm_param_keep {
	int KeepNumEn; //0/1:enable the keep infinite/finite time
	int KeepDampEn;//0/1:Full-width/Attenuated pwm
	int KeepDamp;//Set attenuated ratio
	int KeepNum;//the period of pwm when KeepNumEn is 1
};
#endif

struct fh_sm_param {
	enum fh_sm_mode mode;
	int direction;
	int output_invert_A;
	int output_invert_B;
	unsigned int manual_pwm_choosenA;// please lookup doc to set
	unsigned int manual_pwm_choosenB;// please lookup doc to set
	struct fh_sm_timingparam timingparam;
#ifdef CONFIG_FH_STEPMOTOR_V1_1
	struct fh_sm_param_init initparam;
	int keep;
	struct fh_sm_param_autostop autostopparam;
#endif
#ifdef CONFIG_FH_STEPMOTOR_V1_2
	int dampen;//0/1:Full-width/Attenuated pwm
	int damp;//Set attenuated ratio
	struct fh_sm_param_keep keepparam;
#endif

};

struct fh_sm_lut {
	int lutsize;
	int *lut;
};

struct fh_sm_obj_t {
	int irq_no;
	void* regs;
	struct clk *clk;
	struct completion	run_complete;
	char isrname[24];
	int id;
};


irqreturn_t fh_stepmotor_isr(int irq, void *dev_id);
int fh_stepmotor_is_busy(struct fh_sm_obj_t *obj);
void fh_stepmotor_set_hw_param(struct fh_sm_obj_t *obj,
	struct fh_sm_param *param);
void fh_stepmotor_get_hw_param(struct fh_sm_obj_t *obj,
	struct fh_sm_param *param);
int fh_stepmotor_start_sync(struct fh_sm_obj_t *obj,
	int cycles);
void fh_stepmotor_start_async(struct fh_sm_obj_t *obj,
	int cycles);
#ifdef CONFIG_FH_STEPMOTOR_V1_2
void fh_stepmotor_update_cycle(struct fh_sm_obj_t *obj, int cycles);
#endif
int fh_stepmotor_stop(struct fh_sm_obj_t *obj);
int fh_stepmotor_get_current_cycle(struct fh_sm_obj_t *obj);
int fh_stepmotor_set_lut(struct fh_sm_obj_t *obj,struct fh_sm_lut *lut);
int fh_stepmotor_get_lutsize(struct fh_sm_obj_t *obj);
int fh_stepmotor_get_lut(struct fh_sm_obj_t* obj,struct fh_sm_lut *lut);
void fh_stepmotor_init_hw_param(struct fh_sm_obj_t *obj);
#endif /* FH_STEPMOTOR_HW_H_ */
